package com.shopping.mall.core.module.cart.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.shopping.mall.auth.annotation.UnLogin;
import com.shopping.mall.auth.utils.UserUtils;
import com.shopping.mall.base.entity.KeyValue;
import com.shopping.mall.core.module.attributeKey.entity.AttributeKey;
import com.shopping.mall.core.module.attributeKey.mapper.AttributeKeyMapper;
import com.shopping.mall.core.module.attributeValue.entity.AttributeValue;
import com.shopping.mall.core.module.attributeValue.mapper.AttributeValueMapper;
import com.shopping.mall.core.module.cart.entity.Cart;
import com.shopping.mall.core.module.cart.entity.CartList;
import com.shopping.mall.core.module.cart.mapper.CartMapper;
import com.shopping.mall.core.module.cart.service.CartService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shopping.mall.base.http.ResponseState;
import com.shopping.mall.base.http.Result;
import com.shopping.mall.base.util.WrapperUtils;
import com.shopping.mall.core.module.freight.entity.Freight;
import com.shopping.mall.core.module.freight.mapper.FreightMapper;
import com.shopping.mall.core.module.goods.entity.Goods;
import com.shopping.mall.core.module.goodsSpecification.entity.GoodsSpecification;
import com.shopping.mall.core.module.goodsSpecification.entity.NumPrice;
import com.shopping.mall.core.module.goodsSpecification.entity.NumPriceList;
import com.shopping.mall.core.module.goodsSpecification.mapper.GoodsSpecificationMapper;
import com.shopping.mall.core.module.goodsSpecification.mapper.NumPriceMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.math.BigDecimal;
import java.util.*;

/**
 * <p>
 *  Cart服务实现类
 * </p>
 *
 * @author zzy
 * @since 2021-08-15
 */
@Validated
@Service
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements CartService {

    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private NumPriceMapper numPriceMapper;

    @Autowired
    private GoodsSpecificationMapper goodsSpecificationMapper;

    @Autowired
    private FreightMapper freightMapper;

    @Autowired
    private AttributeKeyMapper attributeKeyMapper;

    @Autowired
    private AttributeValueMapper attributeValueMapper;

    /**
     * 分页查询
     * @param current：页码
     * @param size：每页条数
     * @param cart：筛选条件
     * @return IPage<Cart>
     */
    @Override
    public IPage<Cart> getCartPage(Integer current,Integer size,Cart cart){
        QueryWrapper<Cart> queryWrapper = WrapperUtils.queryWrapper(cart);
        Page<Cart> cartPage = new Page<>(current,size);
        IPage<Cart> cartIPage = cartMapper.selectPage(cartPage, queryWrapper);
        return cartIPage;
    }

    /**
     * 查询所有
     * @param cart ：筛选条件
     * @return List<Cart>
     */
    @Override
    public CartList getAll(Cart cart){
        cart.setUserId(UserUtils.getLoginUserId());
        CartList cartList=cartMapper.getAll(cart);
        if(cartList==null){
            cartList=new CartList();
        }
        cartList.setGoodsPrice(0.0);
        List<String> specificationIds=new ArrayList<>();
        List<String> goodIds=new ArrayList<>();
        //购物车且未添加到稍后购买的商品
        List<Cart> buyGoods=new ArrayList<>();
        //判断是否是稍后购买
        if(cartList.getCartList()!=null&&cartList.getCartList().size()>0){
            for(Cart cartNode:cartList.getCartList()){
                goodIds.add(cartNode.getGoodId());
                if(cartNode.getLaterBuy()==1){
                    specificationIds.add(cartNode.getSpecificationId());
                    buyGoods.add(cartNode);
                }
            }
        }
        //查询key
        List<AttributeKey> keys=new ArrayList<>();
        if(goodIds.size()>0){
            QueryWrapper<AttributeKey> attributeKeyQueryWrapper=new QueryWrapper<>();
            attributeKeyQueryWrapper.in("goods_id",goodIds);
            keys=attributeKeyMapper.selectList(attributeKeyQueryWrapper);
        }
        Map<String,String> keyMap=new HashMap<>();
        List<String> keyIds=new ArrayList<>();
        if(keys!=null&&keys.size()>0){
            for(AttributeKey attributeKey:keys){
                keyMap.put(attributeKey.getId(),attributeKey.getAttributeKey());
                keyIds.add(attributeKey.getId());
            }
        }
        //查询value
        List<AttributeValue> values=new ArrayList<>();
        if(keyIds.size()>0){
            QueryWrapper<AttributeValue> attributeValueQueryWrapper=new QueryWrapper<>();
            attributeValueQueryWrapper.in("attribute_id",keyIds);
            values=attributeValueMapper.selectList(attributeValueQueryWrapper);
        }
        Map<String,String> valueMap=new HashMap<>();
        if(values!=null&&values.size()>0){
            for(AttributeValue attributeValue:values){
                valueMap.put(attributeValue.getId(),attributeValue.getAttributeValue());
            }
        }
        //设置规格详细信息
        if(cartList.getCartList()!=null&&cartList.getCartList().size()>0){
            Iterator<Cart> cartIterable=cartList.getCartList().iterator();
            while (cartIterable.hasNext()){
                Cart cartNode=cartIterable.next();
                try {
                    String specificationJson=cartNode.getGood().getSpecification().getSpecification();
                    JSONArray specificationArray=JSONArray.parseArray(specificationJson);
                    List<KeyValue> specificationKeyValue=specificationArray.toJavaList(KeyValue.class);
                    List<KeyValue> specificationDetailKeyValue=new ArrayList<>();
                    for(KeyValue keyValue:specificationKeyValue){
                        specificationDetailKeyValue.add(new KeyValue(keyMap.get(keyValue.getKey()),valueMap.get(keyValue.getValue())));
                    }
                    cartNode.getGood().getSpecification().setSpecification(JSON.toJSONString(specificationDetailKeyValue));
                } catch (NullPointerException e) {
                    //去掉规格已不存在的商品
                    cartIterable.remove();
                    buyGoods.remove(cartNode);
                }
            }
        }
        //根据数量求商品价格
        List<NumPriceList> numPriceLists=numPriceMapper.selectNumPriceList(specificationIds);
        Map<String, List<NumPrice>> numPriceMap=NumPriceList.toMap(numPriceLists);
        if(buyGoods!=null&&buyGoods.size()>0){
            for(Cart cartNode:buyGoods){
                List<NumPrice> numPriceList=numPriceMap.get(cartNode.getSpecificationId());
                if(numPriceList!=null&&numPriceList.size()>0){
                    numPriceList.sort(new Comparator<NumPrice>() {
                        @Override
                        public int compare(NumPrice numPrice, NumPrice numPrice2) {
                            return numPrice.getNumber()-numPrice2.getNumber();
                        }
                    });
                    for(NumPrice numPrice:numPriceList){
                        if(numPrice.getNumber()>cartNode.getNumber()){
                            break;
                        }
                        cartNode.setPrice(numPrice.getRealPrice());
                    }
                }
                cartList.setGoodsPrice(cartNode.getPrice()*cartNode.getNumber()+cartList.getGoodsPrice());
            }
        }
        //计算运费
        cartList.setFreightPrice(freightMapper.getFreightByPrice(cartList.getGoodsPrice()));
        //计算总价格
        cartList.setTotalPrice(cartList.getFreightPrice()+cartList.getGoodsPrice());
        return cartList;
    }

    @Override
    public CartList getAll(){
        Cart cart=new Cart();
        BigDecimal goodsPriceList=new BigDecimal("0.00");
        cart.setUserId(UserUtils.getLoginUserId());
        //所有商品，包括稍后购买
        CartList cartList=cartMapper.getAll(cart);
        if(cartList!=null){
            cartList.setGoodsPrice(0.0);
            List<String> specificationIds=new ArrayList<>();
            List<String> goodIds=new ArrayList<>();
            List<Cart> buyGoods=new ArrayList<>();
            //判断是否是稍后购买
            if(cartList.getCartList()!=null&&cartList.getCartList().size()>0){
                for(Cart cartNode:cartList.getCartList()){
                    goodIds.add(cartNode.getGoodId());
                    if(cartNode.getLaterBuy()==1){
                        specificationIds.add(cartNode.getSpecificationId());
                        buyGoods.add(cartNode);
                    }
                }
            }
            //查询key
            List<AttributeKey> keys=new ArrayList<>();
            if(goodIds.size()>0){
                QueryWrapper<AttributeKey> attributeKeyQueryWrapper=new QueryWrapper<>();
                attributeKeyQueryWrapper.in("goods_id",goodIds);
                keys=attributeKeyMapper.selectList(attributeKeyQueryWrapper);
            }
            Map<String,String> keyMap=new HashMap<>();
            List<String> keyIds=new ArrayList<>();
            if(keys!=null&&keys.size()>0){
                for(AttributeKey attributeKey:keys){
                    keyMap.put(attributeKey.getId(),attributeKey.getAttributeKey());
                    keyIds.add(attributeKey.getId());
                }
            }
            //查询value
            List<AttributeValue> values=new ArrayList<>();
            if(keyIds.size()>0){
                QueryWrapper<AttributeValue> attributeValueQueryWrapper=new QueryWrapper<>();
                attributeValueQueryWrapper.in("attribute_id",keyIds);
                values=attributeValueMapper.selectList(attributeValueQueryWrapper);
            }
            Map<String,String> valueMap=new HashMap<>();
            if(values!=null&&values.size()>0){
                for(AttributeValue attributeValue:values){
                    valueMap.put(attributeValue.getId(),attributeValue.getAttributeValue());
                }
            }
            //设置规格详细信息
            if(cartList.getCartList()!=null&&cartList.getCartList().size()>0){
                Iterator<Cart> cartIterable=cartList.getCartList().iterator();
                while (cartIterable.hasNext()){
                    Cart cartNode=cartIterable.next();
                    try {
                        String specificationJson=cartNode.getGood().getSpecification().getSpecification();
                        JSONArray specificationArray=JSONArray.parseArray(specificationJson);
                        List<KeyValue> specificationKeyValue=specificationArray.toJavaList(KeyValue.class);
                        List<KeyValue> specificationDetailKeyValue=new ArrayList<>();
                        for(KeyValue keyValue:specificationKeyValue){
                            specificationDetailKeyValue.add(new KeyValue(keyMap.get(keyValue.getKey()),valueMap.get(keyValue.getValue())));
                        }
                        cartNode.getGood().getSpecification().setSpecification(JSON.toJSONString(specificationDetailKeyValue));
                    } catch (NullPointerException e) {
                        //去掉规格已不存在的商品
                        cartIterable.remove();
                        buyGoods.remove(cartNode);
                    }
                }
            }
            //根据数量求商品价格
            List<NumPriceList> numPriceLists=numPriceMapper.selectNumPriceList(specificationIds);
            Map<String, List<NumPrice>> numPriceMap=NumPriceList.toMap(numPriceLists);
            for(Cart cartNode:buyGoods){
                List<NumPrice> numPriceList=numPriceMap.get(cartNode.getSpecificationId());
                if(numPriceList!=null&&numPriceList.size()>0){
                    numPriceList.sort(new Comparator<NumPrice>() {
                        @Override
                        public int compare(NumPrice numPrice, NumPrice numPrice2) {
                            return numPrice.getNumber()-numPrice2.getNumber();
                        }
                    });
                    for(NumPrice numPrice:numPriceList){
                        if(numPrice.getNumber()>cartNode.getNumber()){
                            break;
                        }
                        cartNode.setPrice(numPrice.getRealPrice());
                    }

                }
                BigDecimal goodsPrice= BigDecimal.valueOf(cartNode.getPrice());
                goodsPrice=goodsPrice.multiply(new BigDecimal(cartNode.getNumber()));
                goodsPriceList=goodsPriceList.add(goodsPrice);
            }
            cartList.setGoodsPrice(goodsPriceList.doubleValue());
            //计算运费
            cartList.setFreightPrice(freightMapper.getFreightByPrice(cartList.getGoodsPrice()));

            BigDecimal totalPrice= BigDecimal.valueOf(cartList.getFreightPrice());
            totalPrice=totalPrice.add(goodsPriceList);
            //计算总价格
            cartList.setTotalPrice(totalPrice.doubleValue());
        }

        return cartList;
    }

    @Override
    public CartList getByIds(List<String> cartIds) {
        CartList cartList=cartMapper.getByIds(cartIds);
        //所有商品价格
        BigDecimal goodsPriceList=new BigDecimal("0.00");
        if(cartList!=null){
            cartList.setGoodsPrice(0.0);
            //后面查询价格时会用到
            List<String> specificationIds=new ArrayList<>();
            List<String> goodIds=new ArrayList<>();
            //查询key
            List<AttributeKey> keys=new ArrayList<>();
            if(cartList.getCartList()!=null&&cartList.getCartList().size()>0){
                for(Cart cartNode:cartList.getCartList()){
                    goodIds.add(cartNode.getGoodId());
                    specificationIds.add(cartNode.getSpecificationId());
                }
            }
            if(goodIds.size()>0){
                QueryWrapper<AttributeKey> attributeKeyQueryWrapper=new QueryWrapper<>();
                attributeKeyQueryWrapper.in("goods_id",goodIds);
                keys=attributeKeyMapper.selectList(attributeKeyQueryWrapper);
            }
            Map<String,String> keyMap=new HashMap<>();
            List<String> keyIds=new ArrayList<>();
            if(keys!=null&&keys.size()>0){
                for(AttributeKey attributeKey:keys){
                    keyMap.put(attributeKey.getId(),attributeKey.getAttributeKey());
                    keyIds.add(attributeKey.getId());
                }
            }
            //查询value
            List<AttributeValue> values=new ArrayList<>();
            if(keyIds.size()>0){
                QueryWrapper<AttributeValue> attributeValueQueryWrapper=new QueryWrapper<>();
                attributeValueQueryWrapper.in("attribute_id",keyIds);
                values=attributeValueMapper.selectList(attributeValueQueryWrapper);
            }
            Map<String,String> valueMap=new HashMap<>();
            if(values!=null&&values.size()>0){
                for(AttributeValue attributeValue:values){
                    valueMap.put(attributeValue.getId(),attributeValue.getAttributeValue());
                }
            }
            //设置规格详细信息
            if(cartList.getCartList()!=null&&cartList.getCartList().size()>0){
                Iterator<Cart> cartIterable=cartList.getCartList().iterator();
                while (cartIterable.hasNext()){
                    Cart cartNode=cartIterable.next();
                    try {
                        String specificationJson=cartNode.getGood().getSpecification().getSpecification();
                        JSONArray specificationArray=JSONArray.parseArray(specificationJson);
                        List<KeyValue> specificationKeyValue=specificationArray.toJavaList(KeyValue.class);
                        List<KeyValue> specificationDetailKeyValue=new ArrayList<>();
                        for(KeyValue keyValue:specificationKeyValue){
                            specificationDetailKeyValue.add(new KeyValue(keyMap.get(keyValue.getKey()),valueMap.get(keyValue.getValue())));
                        }
                        cartNode.getGood().getSpecification().setSpecification(JSON.toJSONString(specificationDetailKeyValue));
                    } catch (NullPointerException e) {
                        //去掉规格已不存在的商品
                        cartIterable.remove();
                    }
                }
            }
            //根据数量求商品价格
            List<NumPriceList> numPriceLists=numPriceMapper.selectNumPriceList(specificationIds);
            Map<String, List<NumPrice>> numPriceMap=NumPriceList.toMap(numPriceLists);
            for(Cart cartNode:cartList.getCartList()){
                List<NumPrice> numPriceList=numPriceMap.get(cartNode.getSpecificationId());
                if(numPriceList!=null&&numPriceList.size()>0){
                    numPriceList.sort(new Comparator<NumPrice>() {
                        @Override
                        public int compare(NumPrice numPrice, NumPrice numPrice2) {
                            return numPrice.getNumber()-numPrice2.getNumber();
                        }
                    });
                    for(NumPrice numPrice:numPriceList){
                        if(numPrice.getNumber()>cartNode.getNumber()){
                            break;
                        }
                        cartNode.setPrice(numPrice.getRealPrice());
                    }
                }
                BigDecimal goodsPrice= BigDecimal.valueOf(cartNode.getPrice());
                goodsPrice=goodsPrice.multiply(new BigDecimal(cartNode.getNumber()));
                goodsPriceList=goodsPriceList.add(goodsPrice);
            }
            cartList.setGoodsPrice(goodsPriceList.doubleValue());
            //计算运费
            cartList.setFreightPrice(freightMapper.getFreightByPrice(cartList.getGoodsPrice()));

            BigDecimal totalPrice= BigDecimal.valueOf(cartList.getFreightPrice());
            totalPrice=totalPrice.add(goodsPriceList);
            //计算总价格
            cartList.setTotalPrice(totalPrice.doubleValue());
        }
        return cartList;
    }

    /**
     * 通过id删除
     * @param id：cartId
     * @return Result<Object>
     */
    @Override
    public Result<Object> deleteById(String id){
        Cart cart=cartMapper.selectById(id);
        if(cart==null){
            return Result.error(ResponseState.TARGET_NOT_EXIST.getValue(), ResponseState.TARGET_NOT_EXIST.getMessage());
        }
        cartMapper.deleteById(id);
        return Result.OK(getAll());
    }

    /**
    * 批量删除
    * @param ids：id列表
    * @return Result<Object>
    */
    @Override
    public Result<Object> batchDelete(List<String> ids){
        UpdateWrapper<Cart> updateWrapper=new UpdateWrapper<>();
        updateWrapper.in("id",ids);
        cartMapper.delete(updateWrapper);
        return Result.OK(getAll());
    }


    /**
     * 添加购物车
     * @param cart ：商品
     * @return Result<Object>
     */
    @Override
    public Result<Object> add(Cart cart) {
        cart.setUserId(UserUtils.getLoginUserId());
        QueryWrapper<Cart> cartQueryWrapper=new QueryWrapper<>();
        cartQueryWrapper.eq("user_id",cart.getUserId());
        cartQueryWrapper.eq("specification_id",cart.getSpecificationId());
        Cart oldCart=cartMapper.selectOne(cartQueryWrapper);
        if(oldCart!=null){
            oldCart.setNumber(oldCart.getNumber()+cart.getNumber());
            cartMapper.updateById(oldCart);
            return Result.OK(getAll());
        }
        GoodsSpecification goodsSpecification=goodsSpecificationMapper.selectById(cart.getSpecificationId());
        if(goodsSpecification==null){
            return Result.error(ResponseState.SPECIFICATION_NOT_EXIST.getValue(),ResponseState.SPECIFICATION_NOT_EXIST.getMessage());
        }
        if(cart.getNumber()==null){
            cart.setNumber(1);
        }
        cartMapper.insert(cart);
        return Result.OK(getAll());
    }

    public static void main(String[] args) {
        System.out.println(a());
    }

    public static int a(){
        try {
            return 1;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            return 2;
        }
    }

}